import java.util.ArrayList;
import java.util.List;

// 定义组件接口，所有具体组件和装饰器都需实现该接口，用于定义统一的操作行为
interface Component {
    void operation();
}

// 具体组件类，实现Component接口，代表最基础的被装饰对象，提供基础的操作实现
class ConcreteComponent implements Component {
    @Override
    public void operation() {
        System.out.println("ConcreteComponent operation.");
    }
}

// 装饰器抽象类，持有一个Component的引用，并实现Component接口，
// 作为所有具体装饰器的抽象基类，为具体装饰器提供公共的结构和行为逻辑
abstract class Decorator implements Component {
    // 持有被装饰的组件对象，通过构造函数传入，后续操作中基于此组件进行扩展
    protected Component component;

    // 构造函数，添加参数合法性检查，确保传入的组件对象不为空，避免后续出现空指针问题
    public Decorator(Component component) {
        if (component == null) {
            throw new IllegalArgumentException("Component cannot be null");
        }
        this.component = component;
    }

    @Override
    public void operation() {
        if (component!= null) {
            component.operation();
        }
    }
}

// 具体装饰器类A，继承自装饰器抽象类，在原有组件操作基础上增加了额外的行为A
class ConcreteDecoratorA extends Decorator {
    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        // 先执行被装饰组件的原有操作
        super.operation();
        // 再执行具体装饰器A添加的额外行为
        additionalBehaviorForA();
    }

    // 定义具体装饰器A添加的行为，这里只是简单打印一行信息，可以根据实际需求替换为更复杂的逻辑
    private void additionalBehaviorForA() {
        System.out.println("ConcreteDecoratorA added specific behavior.");
    }
}

// 具体装饰器类B，继承自装饰器抽象类，在原有组件操作基础上增加了额外的行为B
class ConcreteDecoratorB extends Decorator {
    public ConcreteDecoratorB(Component component) {
        super(component);
    }

    @Override
    public void operation() {
        // 先执行具体装饰器B添加的额外行为
        additionalBehaviorForB();
        // 再执行被装饰组件的原有操作
        super.operation();
    }

    // 定义具体装饰器B添加的行为，这里只是简单打印一行信息，可以根据实际需求替换为更复杂的逻辑
        private void additionalBehaviorForB() {
            System.out.println("ConcreteDecoratorB added specific behavior.");
        }
}

// 测试装饰者模式
public class DecoratorPatternDemo {
    public static void main(String[] args) {
        // 创建具体组件对象，作为最基础的被装饰对象
        Component component = new ConcreteComponent();

        // 使用具体装饰器A装饰组件对象，此时返回的对象已经是被装饰后的对象了
        Component decoratorA = new ConcreteDecoratorA(component);

        // 再使用具体装饰器B装饰上一步得到的已被装饰的对象，进一步扩展功能
        Component decoratorB = new ConcreteDecoratorB(decoratorA);

        // 执行操作，会按照装饰器的嵌套顺序依次执行各个装饰器添加的行为以及原始组件的行为
        decoratorB.operation();
    }
}